home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0"?>
-
- <!DOCTYPE bindings [
- <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
- %globalDTD;
- ]>
-
- <bindings id="tabBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
- <binding id="tab-base">
- <resources>
- <stylesheet src="chrome://global/skin/tabbox.css"/>
- </resources>
- </binding>
-
- <binding id="tabbox"
- extends="chrome://global/content/bindings/tabbox.xml#tab-base">
- <implementation implements="nsIDOMEventListener, nsIAccessibleProvider">
- <property name="accessibleType" readonly="true">
- <getter>
- <![CDATA[
- return Components.interfaces.nsIAccessibleProvider.XULTabBox;
- ]]>
- </getter>
- </property>
-
- <property name="handleCtrlTab">
- <setter>
- <![CDATA[
- this.setAttribute("handleCtrlTab", val);
- return val;
- ]]>
- </setter>
- <getter>
- <![CDATA[
- return (this.getAttribute("handleCtrlTab") != "false");
- ]]>
- </getter>
- </property>
-
- <property name="handleCtrlPageUpDown">
- <setter>
- <![CDATA[
- this.setAttribute("handleCtrlPageUpDown", val);
- return val;
- ]]>
- </setter>
- <getter>
- <![CDATA[
- return (this.getAttribute("handleCtrlPageUpDown") != "false");
- ]]>
- </getter>
- </property>
-
- <field name="_handleMetaAltArrows" readonly="true">
- false
- </field>
-
- <!-- _tabs and _tabpanels are deprecated , there are here for
- backwards compatibility, -->
- <property name="_tabs" readonly="true" onget="return this.tabs;"/>
- <property name="_tabpanels" readonly="true" onget="return this.tabpanels;"/>
-
- <property name="tabs" readonly="true">
- <getter>
- <![CDATA[
- return this.getElementsByTagNameNS(
- "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- "tabs").item(0);
- ]]>
- </getter>
- </property>
-
- <property name="tabpanels" readonly="true">
- <getter>
- <![CDATA[
- return this.getElementsByTagNameNS(
- "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- "tabpanels").item(0);
- ]]>
- </getter>
- </property>
-
- <property name="selectedIndex">
- <getter>
- <![CDATA[
- var tabs = this.tabs;
- return tabs ? tabs.selectedIndex : -1;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- var tabs = this.tabs;
- if (tabs)
- tabs.selectedIndex = val;
- this.setAttribute("selectedIndex", val);
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedTab">
- <getter>
- <![CDATA[
- var tabs = this.tabs;
- return tabs && tabs.selectedItem;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- if (val) {
- var tabs = this.tabs;
- if (tabs)
- tabs.selectedItem = val;
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedPanel">
- <getter>
- <![CDATA[
- var tabpanels = this.tabpanels;
- return tabpanels && tabpanels.selectedPanel;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- if (val) {
- var tabpanels = this.tabpanels;
- if (tabpanels)
- tabpanels.selectedPanel = val;
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <method name="handleEvent">
- <parameter name="event"/>
- <body>
- <![CDATA[
- if (!event.isTrusted) {
- // Don't let untrusted events mess with tabs.
- return;
- }
-
- switch (event.keyCode) {
- case event.DOM_VK_TAB:
- if (event.ctrlKey && !event.altKey && !event.metaKey)
- if (this.tabs && this.handleCtrlTab) {
- this.tabs.advanceSelectedTab(event.shiftKey ? -1 : 1, true);
- event.stopPropagation();
- event.preventDefault();
- }
- break;
- case event.DOM_VK_PAGE_UP:
- if (event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
- if (this.tabs && this.handleCtrlPageUpDown) {
- this.tabs.advanceSelectedTab(-1, true);
- event.stopPropagation();
- event.preventDefault();
- }
- break;
- case event.DOM_VK_PAGE_DOWN:
- if (event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
- if (this.tabs && this.handleCtrlPageUpDown) {
- this.tabs.advanceSelectedTab(1, true);
- event.stopPropagation();
- event.preventDefault();
- }
- break;
- case event.DOM_VK_LEFT:
- if (event.metaKey && event.altKey && !event.shiftKey && !event.ctrlKey)
- if (this.tabs && this._handleMetaAltArrows) {
- var offset = window.getComputedStyle(this, "")
- .direction == "ltr" ? -1 : 1;
- this.tabs.advanceSelectedTab(offset, true);
- event.stopPropagation();
- event.preventDefault();
- }
- break;
- case event.DOM_VK_RIGHT:
- if (event.metaKey && event.altKey && !event.shiftKey && !event.ctrlKey)
- if (this.tabs && this._handleMetaAltArrows) {
- var offset = window.getComputedStyle(this, "")
- .direction == "ltr" ? 1 : -1;
- this.tabs.advanceSelectedTab(offset, true);
- event.stopPropagation();
- event.preventDefault();
- }
- break;
- }
- ]]>
- </body>
- </method>
-
- <field name="_eventNode">this</field>
-
- <property name="eventNode" onget="return this._eventNode;">
- <setter>
- <![CDATA[
- if (val != this._eventNode) {
- val.addEventListener("keypress", this, false);
- this._eventNode.removeEventListener("keypress", this, false);
- this._eventNode = val;
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <constructor>
- switch (this.getAttribute("eventnode")) {
- case "parent": this._eventNode = this.parentNode; break;
- case "window": this._eventNode = window; break;
- case "document": this._eventNode = document; break;
- }
- this._eventNode.addEventListener("keypress", this, false);
- </constructor>
-
- <destructor>
- this._eventNode.removeEventListener("keypress", this, false);
- </destructor>
- </implementation>
- </binding>
-
- <binding id="tabs"
- extends="chrome://global/content/bindings/general.xml#basecontrol">
- <resources>
- <stylesheet src="chrome://global/skin/tabbox.css"/>
- </resources>
-
- <content>
- <xul:spacer class="tabs-left"/>
- <children/>
- <xul:spacer class="tabs-right" flex="1"/>
- </content>
-
- <implementation implements="nsIDOMXULSelectControlElement, nsIAccessibleProvider">
- <constructor>
- <![CDATA[
- // first and last tabs need to be able to have unique styles
- // and also need to select first tab on startup.
- if (this.firstChild)
- this.firstChild.setAttribute("first-tab", "true");
- if (this.lastChild)
- this.lastChild.setAttribute("last-tab", "true");
-
- var o = this.getAttribute("orient");
- if (!o)
- this.setAttribute("orient", "horizontal");
-
- for (var parent = this.parentNode; parent; parent = parent.parentNode) {
- if (parent.localName == "tabbox" && parent.hasAttribute("selectedIndex")) {
- var selectedIndex = parseInt(parent.getAttribute("selectedIndex"));
- this.selectedIndex = selectedIndex > 0 ? selectedIndex : 0;
- return;
- }
- }
-
- var children = this.childNodes;
- var length = children.length;
- for (var i = 0; i < length; i++) {
- if (children[i].getAttribute("selected") == "true") {
- this.selectedIndex = i;
- return;
- }
- }
-
- var value = this.value;
- if (value)
- this.value = value;
- else
- this.selectedIndex = 0;
- ]]>
- </constructor>
-
- <property name="accessibleType" readonly="true">
- <getter>
- <![CDATA[
- return Components.interfaces.nsIAccessibleProvider.XULTabs;
- ]]>
- </getter>
- </property>
-
- <property name="itemCount" readonly="true"
- onget="return this.childNodes.length"/>
-
- <property name="value" onget="return this.getAttribute('value');">
- <setter>
- <![CDATA[
- this.setAttribute("value", val);
- var children = this.childNodes;
- for (var c = children.length - 1; c >= 0; c--) {
- if (children[c].value == val) {
- this.selectedIndex = c;
- break;
- }
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedIndex">
- <getter>
- <![CDATA[
- const tabs = this.childNodes;
- for (var i = 0; i < tabs.length; i++) {
- if (tabs[i].selected)
- return i;
- }
- return -1;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- var tab = this.getItemAtIndex(val);
- if (tab) {
- var alreadySelected = tab.selected;
-
- Array.forEach(this.childNodes, function (aTab) {
- if (aTab.selected && aTab != tab)
- aTab._selected = false;
- });
- tab._selected = true;
-
- this.setAttribute("value", tab.value);
-
- for (var parent = this.parentNode; parent; parent = parent.parentNode) {
- if (parent.localName == 'tabbox') {
- parent.setAttribute("selectedIndex", val);
- var tabpanels = parent.tabpanels;
- // This will cause an onselect event to fire for the tabpanel element.
- if (tabpanels) {
- // find an id
- var linkedPanelId = tab.linkedPanel;
- var linkedPanel = linkedPanelId ? document.getElementById(linkedPanelId) : null;
- if (linkedPanel)
- tabpanels.selectedPanel = linkedPanel;
- else
- tabpanels.selectedIndex = val;
- }
- break;
- }
- }
-
- if (!alreadySelected) {
- // Fire an onselect event for the tabs element.
- var event = document.createEvent('Events');
- event.initEvent('select', true, true);
- this.dispatchEvent(event);
- }
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedItem">
- <getter>
- <![CDATA[
- const tabs = this.childNodes;
- for (var i = 0; i < tabs.length; i++) {
- if (tabs[i].selected)
- return tabs[i];
- }
- return null;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- if (val && !val.selected)
- // The selectedIndex setter ignores invalid values
- // such as -1 if |val| isn't one of our child nodes.
- this.selectedIndex = this.getIndexOfItem(val);
- return val;
- ]]>
- </setter>
- </property>
-
- <method name="getIndexOfItem">
- <parameter name="item"/>
- <body>
- <![CDATA[
- return Array.indexOf(this.childNodes, item);
- ]]>
- </body>
- </method>
-
- <method name="getItemAtIndex">
- <parameter name="index"/>
- <body>
- <![CDATA[
- return this.childNodes.item(index);
- ]]>
- </body>
- </method>
-
- <method name="_selectNewTab">
- <parameter name="aNewTab"/>
- <parameter name="aFallbackDir"/>
- <parameter name="aWrap"/>
- <body>
- <![CDATA[
- var requestedTab = aNewTab;
- while (aNewTab.hidden || aNewTab.disabled) {
- aNewTab = aFallbackDir == -1 ? aNewTab.previousSibling : aNewTab.nextSibling;
- if (!aNewTab && aWrap)
- aNewTab = aFallbackDir == -1 ? this.childNodes[this.childNodes.length - 1] :
- this.childNodes[0];
- if (aNewTab == requestedTab)
- return;
- }
-
- var isTabFocused = false;
- try {
- isTabFocused =
- (document.commandDispatcher.focusedElement == this.selectedItem);
- } catch (e) {}
- this.selectedItem = aNewTab;
- if (isTabFocused) {
- aNewTab.focus();
- }
- else if (this.getAttribute("setfocus") != "false") {
- document.commandDispatcher.advanceFocusIntoSubtree(aNewTab);
-
- // Make sure that the focus doesn't move outside the tabbox
- for (var parent = this.parentNode; parent; parent = parent.parentNode) {
- if (parent.localName == "tabbox") {
- try {
- var el = document.commandDispatcher.focusedElement;
- while (el && el != parent)
- el = el.parentNode;
- if (el != parent)
- aNewTab.focus();
- } catch(e) {
- }
- break;
- }
- }
- }
- ]]>
- </body>
- </method>
-
- <method name="advanceSelectedTab">
- <parameter name="aDir"/>
- <parameter name="aWrap"/>
- <body>
- <![CDATA[
- var startTab = this.selectedItem;
- var next = startTab[aDir == -1 ? "previousSibling" : "nextSibling"];
- if (!next && aWrap) {
- next = aDir == -1 ? this.childNodes[this.childNodes.length - 1] :
- this.childNodes[0];
- }
- if (next && next != startTab) {
- this._selectNewTab(next, aDir, aWrap);
- }
- ]]>
- </body>
- </method>
-
- <method name="appendItem">
- <parameter name="label"/>
- <parameter name="value"/>
- <body>
- <![CDATA[
- var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var tab = document.createElementNS(XULNS, "tab");
- tab.setAttribute("label", label);
- tab.setAttribute("value", value);
- this.appendChild(tab);
- return tab;
- ]]>
- </body>
- </method>
-
- <method name="insertItemAt">
- <parameter name="index"/>
- <parameter name="label"/>
- <parameter name="value"/>
- <body>
- <![CDATA[
- var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var tab = document.createElementNS(XULNS, "tab");
- tab.setAttribute("label", label);
- tab.setAttribute("value", value);
- var before = this.getItemAtIndex(index);
- if (before)
- this.insertBefore(tab, before);
- else
- this.appendChild(tab);
- return tab;
- ]]>
- </body>
- </method>
-
- <method name="removeItemAt">
- <parameter name="index"/>
- <body>
- <![CDATA[
- var remove = this.getItemAtIndex(index);
- if (remove)
- this.removeChild(remove);
- return remove;
- ]]>
- </body>
- </method>
- </implementation>
- </binding>
-
- <!--
- XXXben - this looks like something added specifically for tabbrowser.
- if it turns out no one uses this that can't easily be evangelized to
- use their own roll-your-own binding, then we should get rid of this
- to tighten up the toolkit api. This binding made obsolete in Firefox
- by 308396.
- -->
- <binding id="tabs-closebutton"
- extends="chrome://global/content/bindings/tabbox.xml#tabs">
- <content>
- <xul:hbox flex="1" style="min-width: 1px; overflow: -moz-hidden-unscrollable;">
- <children/>
- <xul:spacer class="tabs-right" flex="1"/>
- </xul:hbox>
- <xul:stack>
- <xul:spacer class="tabs-right"/>
- <xul:hbox class="tabs-closebutton-box" align="center" pack="end">
- <xul:toolbarbutton ondblclick="event.stopPropagation();" class="tabs-closebutton close-button" xbl:inherits="disabled=disableclose,oncommand=onclosetab"/>
- </xul:hbox>
- </xul:stack>
- </content>
- </binding>
-
- <binding id="tabpanels"
- extends="chrome://global/content/bindings/tabbox.xml#tab-base">
- <implementation>
-
- <field name="_selectedPanel">this.childNodes.item(this.selectedIndex)</field>
-
- <property name="selectedIndex">
- <getter>
- <![CDATA[
- var indexStr = this.getAttribute("selectedIndex");
- return indexStr ? parseInt(indexStr) : -1;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- if (val < 0 || val >= this.childNodes.length)
- return val;
- var panel = this._selectedPanel;
- this._selectedPanel = this.childNodes[val];
- this.setAttribute("selectedIndex", val);
- if (this._selectedPanel != panel) {
- var event = document.createEvent("Events");
- event.initEvent("select", true, true);
- this.dispatchEvent(event);
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedPanel">
- <getter>
- <![CDATA[
- return this._selectedPanel;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- var selectedIndex = -1;
- for (var panel = val; panel != null; panel = panel.previousSibling)
- ++selectedIndex;
- this.selectedIndex = selectedIndex;
- return val;
- ]]>
- </setter>
- </property>
- </implementation>
- </binding>
-
- <binding id="tab" display="xul:button"
- extends="chrome://global/content/bindings/general.xml#control-item">
- <resources>
- <stylesheet src="chrome://global/skin/tabbox.css"/>
- </resources>
-
- <content chromedir="&locale.dir;">
- <xul:hbox class="tab-middle box-inherit" xbl:inherits="align,dir,pack,orient,selected" flex="1">
- <xul:image class="tab-icon" xbl:inherits="validate,src=image"/>
- <xul:label class="tab-text" xbl:inherits="value=label,accesskey,crop,disabled" flex="1"/>
- </xul:hbox>
- </content>
-
- <implementation implements="nsIDOMXULSelectControlItemElement, nsIAccessibleProvider">
- <property name="accessibleType" readonly="true">
- <getter>
- <![CDATA[
- return Components.interfaces.nsIAccessibleProvider.XULTab;
- ]]>
- </getter>
- </property>
-
- <property name="control" readonly="true">
- <getter>
- <![CDATA[
- var parent = this.parentNode;
- if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
- return parent;
- return null;
- ]]>
- </getter>
- </property>
-
- <property name="selected" readonly="true"
- onget="return this.getAttribute('selected') == 'true';"/>
-
- <property name="_selected">
- <setter>
- <![CDATA[
- this.setAttribute("selected", val);
- if (this.previousSibling && this.previousSibling.localName == "tab") {
- if (val)
- this.previousSibling.setAttribute("beforeselected", val);
- else
- this.previousSibling.removeAttribute("beforeselected");
- this.removeAttribute("first-tab");
- }
- else
- this.setAttribute("first-tab", "true");
-
- if (this.nextSibling && this.nextSibling.localName == "tab") {
- if (val)
- this.nextSibling.setAttribute("afterselected", val);
- else
- this.nextSibling.removeAttribute("afterselected");
- this.removeAttribute("last-tab");
- }
- else
- this.setAttribute("last-tab", "true");
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="linkedPanel" onget="return this.getAttribute('linkedpanel')"
- onset="this.setAttribute('linkedpanel', val); return val;"/>
-
- <field name="arrowKeysShouldWrap" readonly="true">
- false
- </field>
- </implementation>
-
- <handlers>
- <handler event="mousedown" button="0">
- <![CDATA[
- if (this.disabled)
- return;
-
- if (this != this.parentNode.selectedItem) { // Not selected yet
- // Select new tab after short delay so that PostHandleEvent() doesn't see
- // the tab as selected yet, otherwise it will focus the tab for us --
- // the CSS for tab has -moz-user-focus: normal only for selected="true".
- function setTab(tab) {
- tab.parentNode._selectNewTab(tab);
- }
- setTimeout(setTab, 0, this);
- }
- // Otherwise this tab is already selected and we will fall
- // through to mousedown behavior which sets focus on the current tab,
- // Only a click on an already selected tab should focus the tab itself.
- ]]>
- </handler>
-
- <handler event="keypress" keycode="VK_LEFT">
- <![CDATA[
- var direction = window.getComputedStyle(this.parentNode, null).direction;
- this.parentNode.advanceSelectedTab(direction == 'ltr' ? -1 : 1, this.arrowKeysShouldWrap);
- ]]>
- </handler>
-
- <handler event="keypress" keycode="VK_RIGHT">
- <![CDATA[
- var direction = window.getComputedStyle(this.parentNode, null).direction;
- this.parentNode.advanceSelectedTab(direction == 'ltr' ? 1 : -1, this.arrowKeysShouldWrap);
- ]]>
- </handler>
-
- <handler event="keypress" keycode="VK_UP">
- <![CDATA[
- this.parentNode.advanceSelectedTab(-1, this.arrowKeysShouldWrap);
- ]]>
- </handler>
-
- <handler event="keypress" keycode="VK_DOWN">
- <![CDATA[
- this.parentNode.advanceSelectedTab(1, this.arrowKeysShouldWrap);
- ]]>
- </handler>
-
- <handler event="keypress" keycode="VK_HOME">
- <![CDATA[
- this.parentNode._selectNewTab(this.parentNode.childNodes[0]);
- ]]>
- </handler>
-
- <handler event="keypress" keycode="VK_END">
- <![CDATA[
- var tabs = this.parentNode.childNodes;
- this.parentNode._selectNewTab(tabs[tabs.length - 1], -1);
- ]]>
- </handler>
- </handlers>
- </binding>
-
- </bindings>
-
-